package com.util;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.config.ConstDefine;


/**
 * 距离计算工具
 * 
 * @author lepin
 * 
 */
public class DistanceHelper {
	private static final String baiduDirectionUrl = "http://api.map.baidu.com/direction/v1";
	private static final double EARTH_RADIUS = 6378137.0;//地球直径

	public static void main(String[] args) {
//		System.out.println(distanceOf2PointOfBaidu("45.4496861434657,128.31872300000035","45.46672294957571, 128.33119749848203","?????????"));
//		System.out.println(distanceOf2PointOfBaidu_driver("45.455268412004514,128.30879211425798","45.460034780712476, 128.34679208213535","哈尔滨市"));
//		getDistance("");
		System.out.println(getDistance("45.75762420679768, 126.66529875011445","45.75702162427602, 126.66523437709809"));
//		System.out.println(getPoint("黑龙江省哈尔滨市福泰名苑").toString());
//		point2City("45.75762420679768,126.66529875011445");
//		System.out.println(point2City("45.768233715973096,126.66923086853028"));
		System.out.println(getPoint("哈尔滨市福泰名苑"));
		System.out.println(getPoint("哈尔滨市福泰名苑往东2000米"));
	}
	/**
	 * 坐标转地市
	 * @param location
	 * @return
	 */
	public static JSONObject point2City(String location)
	{
		JSONObject json=new JSONObject();
		try {
			json.put("code", "01");
			String res=HttpKit.get("https://apis.map.qq.com/ws/geocoder/v1/?key="+ConstDefine.txkey+"&location="+location);
			System.out.println(res);
			if(StrKit.notBlank(res))
			{
				JSONObject txres=new JSONObject(res);
				if(txres.getInt("status")==0&&txres.getString("message").equals("query ok"))
				{
					JSONObject values=txres.getJSONObject("result").getJSONObject("address_component");
					json.put("code", "00");
					json.put("province", values.getString("province").replace("省", "").replace("市", ""));
					json.put("city", values.getString("city"));
					json.put("area", values.getString("district"));
				}
			}
			System.out.println(json.toString());
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return json;
	}
	
	/**
	 * 根据路由点集，计算路程
	 * @param routeJson
	 * @return
	 */
	public static double getDistance(String routeJson)
	{
		double res=0.0;
//		routeJson=DBDemo.getStr();
//		System.out.println(routeJson);
		if(routeJson!=null&&routeJson.contains("LatLng"))
		{
			JSONObject jso;
			try {
				jso = new JSONObject(routeJson);
				JSONObject jsoCache0=new JSONObject();
				JSONObject jsoCache1=new JSONObject();
				JSONArray arr=jso.getJSONArray("LatLng");
				if(arr!=null&&arr.length()>1)
				{
					for(int i=1;i<arr.length();i++)
					{
						jsoCache0=arr.getJSONObject(i-1);
						jsoCache1=arr.getJSONObject(i);
//						System.out.println(i+":"+jsoCache.getDouble("latitude")+"-"+jsoCache.getDouble("longitude"));
						res=res+getDistance(jsoCache0.getDouble("longitude"), jsoCache0.getDouble("latitude"), jsoCache1.getDouble("longitude"), jsoCache1.getDouble("latitude"));
					}
				}
			} catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
		}
		res=res/1000;
		return res;
	}
	
	/**
	 * 计算两个坐标点的间距_勾股定理
	 * @param longitude1  第一个点经度
	 * @param latitude1   第一个点纬度
	 * @param longitude2  第二个点经度
	 * @param latitude2   第二个点纬度
	 * @return  两点间距离
	 */
	public static double getDistance(double longitude1, double latitude1,
	                                 double longitude2, double latitude2) {
	    double Lat1 = rad(latitude1);
	    double Lat2 = rad(latitude2);
	    double distanceLat = Lat1 - Lat2;
	    double distanceLon = rad(longitude1) - rad(longitude2);
	    double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(distanceLat / 2), 2)
	            + Math.cos(Lat1) * Math.cos(Lat2)
	            * Math.pow(Math.sin(distanceLon / 2), 2)));
	    distance = distance * EARTH_RADIUS;
	    distance = Math.round(distance * 10000) / 10000;
	    return distance;
	}
	
	/**
	 * 计算两个坐标点的间距_勾股定理,单位：米
	 * @param origin  第一个点纬度，精度
	 * @param destination   第2个点纬度，精度
	 * @return  两点间距离
	 */
	public static double getDistance(String origin,String destination) 
	{
//		System.out.println("origins:"+origin);
		String[] origins=origin.split(",");
		String[] destinations=destination.split(",");
	    double Lat1 = rad(Double.parseDouble(origins[0]));
	    double Lat2 = rad(Double.parseDouble(destinations[0]));
	    double distanceLat = Lat1 - Lat2;
	    double distanceLon = rad(Double.parseDouble(origins[1])) - rad(Double.parseDouble(destinations[1]));
	    double distance = 2 * Math.asin(Math.sqrt(Math.pow(Math.sin(distanceLat / 2), 2)
	            + Math.cos(Lat1) * Math.cos(Lat2)
	            * Math.pow(Math.sin(distanceLon / 2), 2)));
	    distance = distance * EARTH_RADIUS;
	    distance = Math.round(distance * 10000) / 10000;
	    return distance;
	}
	private static double rad(double d) {
	    return d * Math.PI / 180.0;
	}
	
	/**
	 * 使用百度接口计算2点之间距离,开车
	 * 
	 * @param origin
	 * @param destination
	 * @param city
	 * @return
	 */
	public static int distanceOf2PointOfBaidu_driver(String origin,
			String destination, String city) {
//		System.out.println("ori :"+origin+"         des is :"+destination+"     cit:"+city);
		String result = "";
		try {
			Map paras = new HashMap();
			paras.put("origin", origin.trim());
			paras.put("mode", "driving");
			paras.put("destination", destination.trim());
			paras.put("origin_region", city);
			paras.put("destination_region", city);
			paras.put("output", "json");
			paras.put("ak", "ZrP1oY4BRE4yMVbEMMh3wHDD8SaeCyIL");
			result = HttpKit
					.get("http://api.map.baidu.com/direction/v1", paras);
			int distance = new JSONObject(new JSONArray(new JSONObject(
					new JSONObject(result).get("result").toString()).get(
					"routes").toString()).get(0).toString()).getInt("distance");
			return distance;
		} catch (Exception e) {
			System.out.println("计算距离发生异常，result:" + result);
			e.printStackTrace();
			return 9999;
		}
	}
	/**
	 * 使用百度接口计算2点之间距离
	 * 
	 * @param origin
	 * @param destination
	 * @param city
	 * @return
	 */
	public static int distanceOf2PointOfBaidu(String origin,
			String destination, String city) {
		
		System.out.println("ori :"+origin+"         des is :"+destination+"     cit:"+city);
		String result = "";
		try {
			Map paras = new HashMap();
			paras.put("origin", origin.trim());
			paras.put("destination", destination.trim());
			paras.put("origin_region", city);
			paras.put("destination_region", city);
			paras.put("output", "json");
			paras.put("ak", "ZrP1oY4BRE4yMVbEMMh3wHDD8SaeCyIL");
			result = HttpKit
					.get("http://api.map.baidu.com/direction/v1", paras);
			int distance = new JSONObject(new JSONArray(new JSONObject(
					new JSONObject(result).get("result").toString()).get(
					"routes").toString()).get(0).toString()).getInt("distance");
			System.out.println("dis is :"+distance);
			return distance;
		} catch (Exception e) {
			System.out.println("计算距离发生异常，result:" + result);
			e.printStackTrace();
			return 9999;
		}
	}
	/**
	 * 根据建筑名称获取坐标--腾讯坐标系
	 * @param addr
	 * @return
	 */
	public static JSONObject getPoint(String addr)
	{
		JSONObject json_result=new JSONObject();
		String addrEncode="";
		try {
			addrEncode=URLEncoder.encode(addr, "utf-8");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		JSONObject json;
		try {
			json = new JSONObject(HttpKit.get("https://apis.map.qq.com/ws/geocoder/v1/?address="+addrEncode+"&key="+ConstDefine.txkey));
			System.out.println("腾讯结果："+json);
			if(json!=null&&json.getInt("status")==0)
			{
				json_result.put("code", "00");
				json_result.put("lng", json.getJSONObject("result").getJSONObject("location").getDouble("lng"));
				json_result.put("lat", json.getJSONObject("result").getJSONObject("location").getDouble("lat"));
			}else{
				json_result.put("code", "03");
			}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
//		System.out.println("查询坐标："+json_result.toString());
		return json_result;
	}

	public static int distanceOfABCD(String pointA, String pointB,
			String pointC, String pointD, String city) {
		return distanceOf2PointOfBaidu(pointA, pointB, city)
				+ distanceOf2PointOfBaidu(pointB, pointC, city)
				+ distanceOf2PointOfBaidu(pointC, pointD, city);
	}

	public static JSONObject getLocationInfo(String lat, String lng) {
		String url = "http://api.map.baidu.com/geocoder/v2/?location=" + lat
				+ "," + lng
				+ "&output=json&ak=ZrP1oY4BRE4yMVbEMMh3wHDD8SaeCyIL&pois=0";
		System.out.println();
		String str = HttpKit.get(url);
		// String str = HttpUtil.getRequest(url, new String[0]);
		JSONObject jsonObject=null;
		try {
			jsonObject = new JSONObject(str);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return jsonObject;
	}

	public static String getProviceName(String lat, String lng) {
		JSONObject jsonObject = getLocationInfo(lat, lng);
		JSONObject json;
		String provinceName=null;
		try {
			json = (JSONObject) jsonObject.get("result");
			JSONObject j = (JSONObject) json.get("addressComponent");
			provinceName = j.getString("province");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return provinceName;
	}

	public static String getCityName(String lat, String lng) {
		JSONObject jsonObject = getLocationInfo(lat, lng);
		JSONObject json;
		String cityName=null;
		try {
			json = (JSONObject) jsonObject.get("result");
			JSONObject j = (JSONObject) json.get("addressComponent");
			cityName = j.getString("city");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return cityName;
	}

	public static String getAreaName(String lat, String lng) {
		JSONObject jsonObject = getLocationInfo(lat, lng);
		JSONObject json;
		String districtName = null;
		try {
			json = (JSONObject) jsonObject.get("result");
			JSONObject j = (JSONObject) json.get("addressComponent");
			districtName = j.getString("district");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return districtName;
	}
}
